<?php

namespace mongrove;

use Iterator;
use Countable;

/**
 * The QueryResult
 *
 * @author Gido Hakvoort <gido@hakvoort.it>
 * @author Michiel Hakvoort <michiel@hakvoort.it>
 *
 */
class QueryResult implements Iterator, Countable {

    /**
     *
     * @var MongoCursor
     */
    protected $cursor = null;

    public function __construct(\MongoCursor $cursor) {
        $this->cursor = $cursor;
    }

    /**
     * Return the amount of results in the QueryResult. Additionally the
     * size of the result without limits can be returned as well.
     *
     * @param boolean $all If set to true, return the amount of entries if no limits were set
     *
     * @return The amount of Records to be found in the query result
     */
    public function count($all = false) {
        return $this->cursor->count($all);
    }

    /**
     * (non-PHPdoc)
     * @see Iterator::current()
     */
    public function current() {
        $result = $this->cursor->current();

        if(!isset($result[Constant :: TYPES])) {
            throw new \Exception("Could not map result, '_types' missing");
        }
        $class = new $result[Constant :: TYPES][0];
        $class->hydrate($result);
        $class->clean();

        return $class;
    }

    /**
     * Hydrate all Records into an array. This method is a simple wrapper for
     * the iterator_to_array function.
     *
     * @return array[Record]
     */
    public function toObjectArray() {
        return iterator_to_array($this);
    }

    /**
     * Return the next Record from the QueryResult
     *
     * @return Record
     */
    public function getNext() {
        $result = $this->cursor->getNext();

        if(!isset($result[Constant :: TYPES])) {
            throw new \Exception("Could not map result, '_types' missing");
        }

        $record = new $result[Constant :: TYPES][0];
        $record->hydrate($result);
        $record->clean();

        return $record;
    }

    /**
     * Check whether the QueryResult contains more entries
     *
     * @return boolean True if more entries are contained in the QueryResult
     */
    public function hasNext() {
        return $this->cursor->hasNext();
    }

    /**
     * (non-PHPdoc)
     * @see Iterator::key()
     */
    public function key() {
        return $this->cursor->key();
    }

    /**
     * (non-PHPdoc)
     * @see Iterator::next()
     */
    public function next() {
        $this->cursor->next();
    }

    /**
     * Reset the internal MongoCursor object
     */
    public function reset() {
        $this->cursor->reset();
    }

    /**
     * (non-PHPdoc)
     * @see Iterator::rewind()
     */
    public function rewind() {
        $this->cursor->rewind();
    }

    /**
     * (non-PHPdoc)
     * @see Iterator::valid()
     */
    public function valid() {
        return $this->cursor->valid();
    }
}